// @ts-nocheck
import isGenerator from 'is-generator'
import isPromise from 'is-promise'
import Task from './Task'
import runEffect from './runEffect'
import { isEffect } from './effects/helper'

/**
 * 开启一个新任务
 * @export
 * @param {*} env 全局环境数据，saga执行期共享的数据
 * @param {*} generator 生成器函数
 * @param {*} args 生成器函数参数
 */
export default function runSaga(env, generator, ...args) {

    if (isGenerator(generator)) {
        throw new TypeError('generator must be generator function')
    }

    let iterator = generator(...args)
    return proc(env, iterator)
}

/**
 * 执行一个 generator (iterator) 
 * @param {*} iterator
 */
export function proc(env, iterator) {
    const cbObj = { // 回调函数对象
        callback: () => { }
    }
    /**
     *
     * @param {*} nexValue 正常调用iterator.next时传递的值
     * @param {*} err 错误对象
     * @param {Boolean} isOver 是否结束
     */
    function next(nexValue, err, isOver) {
        let result; // 记录迭代的结果
        if (err) { // 调用iterator.throw()
            result = iterator.throw(err)
        } else if (isOver) {// 调用iterator.return()
            result = iterator.return()
            cbObj.callback('return')
        } else {  // 调用iterator.next()
            result = iterator.next(nexValue)
        }
        const { value, done } = result
        if (done) { //迭代结束 
            cbObj.callback()
            return
        }
        if (isEffect(value)) {  // effect  
            runEffect(env, value, next)
        } else if (isPromise(value)) {  // promise
            value.then(r => next(r)).catch(err => next(null, err))
        } else {
            next(value)
        }
    }
    next()
    return new Task(next, cbObj)

}